﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics.Contracts;

namespace Logger
{
    /// <summary>
    /// A Log consumer that thats generic logging events and sends them to the standard output
    /// </summary>
    /// <remarks>
    /// Useage: 
    /// This class automatically hooks itself up in the static constructor.  Calling any method on this class is sufficient to hook it up (such as Init or BlackListFilter)
    /// </remarks>
    public class ConsoleLogger
    {
        /// <summary>
        /// Logs a message to the console
        /// </summary>
        /// <param name="loggerName">The name of the logger, usually the logger name is the name of the class making the log</param>
        /// <param name="logLevel">The severity of the message to be logged</param>
        /// <param name="cause">An exception which caused the message to be logged (optional)</param>
        /// <param name="message">The text of the message</param>
        public static void Log(String loggerName, LogLevel logLevel, Exception cause, String message)
        {
            Contract.Requires(message != null);
            Contract.Requires(loggerName != null);
            Contract.Requires(System.Console.Out != null);
            if (_BlackListFilter.Contains(loggerName.ToLower()))
            {return;}
            StringBuilder sb = new StringBuilder();
            sb.Append(DateTime.Now.ToString("yyyy-MM-dd T HH:mm:ss"));
            sb.Append(" ");
            sb.Append(logLevel);
            sb.Append(" [");
            sb.Append(loggerName);
            sb.Append("] ");
            sb.AppendLine(message);
            if (cause != null)
            {
                sb.AppendLine(cause.Message);
                sb.AppendLine(cause.StackTrace);
            }
            System.Console.Out.Write(sb.ToString());
        }

        private static List<String> _BlackListFilter = new List<string>();
        /// <summary>
        /// Adds a loggername to a black list.  Messages coming from this logger will be ignored
        /// </summary>
        /// <param name="loggerName"></param>
        public static void BlackListFilter(String loggerName)
        {
            Contract.Requires(loggerName != null);
            _BlackListFilter.Add(loggerName.ToLower());
        }

        /// <summary>
        /// NoOp, this is sufficient however to trigger the ConsoleLogger to hook itself up
        /// </summary>
        public static void Init()
        {
            if (!_didInit)
            { _didInit = true; }
        }
        private static bool _didInit = false;

        /// <summary>
        /// Hooks the console logger up to to the generic logger log source
        /// </summary>
        static ConsoleLogger()
        {
            Logger.Log.OnLog += Log;
        }
    }
}
